package com.momoauth.common.security.aspect;

import com.momoauth.common.security.annotation.RequiresGroup;
import com.momoauth.common.security.dao.GroupDao;
import com.momoauth.common.core.exception.GlobalException;
import com.momoauth.common.security.utils.JwtUtil;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.annotation.Order;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.Optional;

@Aspect
@Order(2)
public class RequiresGroupAspect {

    @Resource
    GroupDao groupDao;

    /**
     * 拦截方法进行群组权限判断
     * @param joinPoint
     */
    @Before("@annotation(com.momoauth.common.security.annotation.RequiresGroup)")
    public void Interceptor(JoinPoint joinPoint) {
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        RequiresGroup requiresGroup = method.getAnnotation(RequiresGroup.class);
        // 判断是否拥有群组权限
        this.handleUserGroup(requiresGroup);
    }

    /**
     * 群组权限判断处理
     * @param requiresGroup
     */
    private void handleUserGroup(RequiresGroup requiresGroup) {
        // 值为空时返回错误信息
        if (requiresGroup.value().equals("")) {
            throw new GlobalException(50000,"@RequiresGroup注解内请填写合法的值。");
        }
        HttpServletRequest request = currentRequest();
        String token = request.getHeader("Authorization");
        // 从头部Token解析出用户ID
        Long userId = Long.parseLong(JwtUtil.getClaimName(token, "userId"));
        String groupName = groupDao.getUserGroupName(userId);
        // 判断群组名称是否一致
        if (StringUtils.isBlank(groupName) || !groupName.equals(requiresGroup.value())) {
            throw new GlobalException(50001,"很抱歉，用户群组权限不足。");
        }
    }

    private HttpServletRequest currentRequest() {
        ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        return Optional.ofNullable(servletRequestAttributes).map(ServletRequestAttributes::getRequest).orElse(null);
    }
}
